package com.vcredit.bird.service.product;


import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import com.vcredit.creditcat.util.HttpRequestExt;
import com.vcredit.framework.annotation.Log;
import com.vcredit.framework.util.HttpRequest;
import io.netty.util.internal.StringUtil;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.Header;
import org.apache.http.message.BasicHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.core.type.TypeReference;
import com.vcredit.bird.api.ICreditProductService;
import com.vcredit.bird.vo.product.crf.CreditCRFResultDto;
import com.vcredit.creditcat.exception.BirdRequestException;
import com.vcredit.creditcat.exception.ProductCanNotApplyException;
import com.vcredit.creditcat.util.Encrypt;
import com.vcredit.framework.util.JacksonUtil;
import com.vcredit.creditcat.util.RSAUtil;


/**
 * Created by liaoshengjun on 2017/8/3.
 */
@Service("creditCRFService")
public class CreditCRFService implements ICreditProductService {
	@Value("${crf.applay.url}")
	private String creditCrftestUrl;

	@Value("${crf.xinyongmao.dataSource}")
	private String dataSource;

	@Value("${crf.xinyongmao.key}")
	private String key;

	@Value("${crf.promotion.url}")
	private String promotionUrl;

	@Value("${crf.promotion.code}")
	private String promotionCode;

	@Value("${crf.promotion.key}")
	private String promotionKey;

	private static Logger logger = LoggerFactory.getLogger(CreditCRFService.class);
	@Log
	@Override
	public Object commit(Object submitDto) throws  Exception {
		Map<String, String> resultMap = new HashMap<>();
		String json = JacksonUtil.Obj2Json(submitDto);
		logger.info("json :"+json);
		String signature=Encrypt.base64HmacMD5(key,json);
		signature=signature.replaceAll("\r\n","");
		logger.info("signature :"+signature);
		try {
			Header[] headers=new Header[3];
			headers[0]=new BasicHeader("X-CrfChina-Signature",signature);
			headers[1]=new BasicHeader("X-Data-Source",dataSource);
			headers[2]=new BasicHeader("Content-Type","application/json");
			String resultJson = HttpRequestExt.doPut(creditCrftestUrl+"/createOrder",json,"UTF-8",headers);
			if(StringUtil.isNullOrEmpty(resultJson)){
				resultMap.put("status","00");
				return resultMap;
			}else{
				String decodeJsonParam = resultJson.replace(":\"\"", ":null");
				CreditCRFResultDto result = JacksonUtil.Json2Obj(decodeJsonParam, new TypeReference<CreditCRFResultDto>(){});
				logger.info(result.getMessage());
				resultMap.put("status","01");
				resultMap.put("message", result.getMessage());
				return resultMap;
			}
		} catch (Exception e) {
			logger.info(e.toString());
			throw new BirdRequestException("网络开小差, 请重新尝试哦。");
		}
	}

	@SuppressWarnings("rawtypes")
	@Override
	public Object checkCredit(Object parmDto) throws ProductCanNotApplyException, Exception {
		String resultJson = "";
		Map<String,String> map=(Map<String, String>) parmDto;
		try {
			String queryPar=toQueryString(map,true);
			byte[] data = queryPar.getBytes();
			byte[] encodedData = RSAUtil.encryptByPublicKey(data,promotionKey);
			String dataCrypted=new String(Base64.encodeBase64(encodedData));
			String sign=URLEncoder.encode(dataCrypted, StandardCharsets.UTF_8.name());
			map.put("systemCode",promotionCode);
			map.put("sign",sign);
			StringBuilder sb=new StringBuilder();
			sb=sb.append(promotionUrl).append("?");
			for(Map.Entry<String,String> entry:map.entrySet()){
				sb=sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
			}
			String url=sb.toString();
			String urlReal=url.substring(0,url.length()-1);
			resultJson=HttpRequest.doGet(urlReal);
			Map result=JacksonUtil.Json2Map(resultJson);
			return result;
		} catch (Exception e) {
			if (e instanceof ProductCanNotApplyException) {
				throw new ProductCanNotApplyException(e.getMessage());
			} else {
				logger.info(e.toString());
				throw new BirdRequestException("网络开小差, 请重新尝试哦。");
			}
		}
	}

	@Override
	public Object getCredit(Object paramDto) throws ProductCanNotApplyException, Exception {
		return null;
	}
	/**
	 * 把一个map拼接成一个get请求查询传
	 * @param map map里面只应有业务查询参数,不应该包含sign和code
	 * @param needEncode 是否使用URLEncode编码,默认为ture
	 * **/
	private String toQueryString(Map<?, ?> data,boolean needEncode)throws UnsupportedEncodingException {
		String[] keys = data.keySet().toArray(new String[data.size()]);
		Arrays.sort(keys);
		StringBuffer queryString = new StringBuffer();
		for (String key : keys) {
			queryString.append(key + "=");
			if(needEncode){
				queryString.append(URLEncoder.encode((String) data.get(key), StandardCharsets.UTF_8.name()) + "&");
			}else{
				queryString.append(data.get(key) + "&");
			}
		}
		if (queryString.length() > 0) {
			queryString.deleteCharAt(queryString.length() - 1);
		}
		return queryString.toString();
	}
}
